package tms.model;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Flight{

    public static final String tableName = "Flight";
    public static String[] columns = {"IDDeparting", "IDArriving", "TotalSeats", "FlightName",
            "IsActive", "Discount", "Price", "Duration", "Price2", "Distance", "IDAircraft",
            "DepDay", "DepMonth", "DepYear", "DepHour", "DepMinute"};

    private int id = -1;
    private int idDeparting = -1;
    private int idArriving = -1;
    private int totalSeats = 0;
    private String flightName = "";
    private boolean isActive = false;
    private double discount = 0;
    private double price = 0;
    private int duration = 0;
    private double price2 = 0;
    private double distance = 0;
    private int idAircraft = -1;

    private int depDay = 1;
    private int depMonth = 1;
    private int depYear = 2013;
    private int depHour = 0;
    private int depMinute = 0;

    private Destination departing = null;
    private Destination arriving = null;
    private Aircraft aircraft = null;

    static Flight createEntityFrom(Map<String, Object> map) {

        Flight entity = new Flight();

        entity.setId((Integer) map.get("Id".toLowerCase()));
        entity.setIdDeparting((Integer) map.get("IDDeparting".toLowerCase()));
        entity.setIdArriving((Integer) map.get("IDArriving".toLowerCase()));
//      entity.setDepartureDate(Helper.ParseDate((String) map.get("DepartureDate".toLowerCase()), DbManager.DATE_FORMAT));
        entity.setTotalSeats((Integer) map.get("TotalSeats".toLowerCase()));
        entity.setFlightName((String) map.get("FlightName".toLowerCase()));
        entity.setActive((Integer) map.get("IsActive".toLowerCase()) == 1);
        entity.setDiscount((Double) map.get("Discount".toLowerCase()));
        entity.setPrice((Double) map.get("Price".toLowerCase()));
        entity.setDuration((Integer) map.get("Duration".toLowerCase()));
        entity.setPrice2((Double) map.get("Price2".toLowerCase()));
        entity.setDistance((Double) map.get("Distance".toLowerCase()));
        entity.setIdAircraft((Integer) map.get("IdAircraft".toLowerCase()));
        entity.depDay = (Integer) map.get("DepDay".toLowerCase());
        entity.depMonth = (Integer) map.get("DepMonth".toLowerCase());
        entity.depYear = (Integer) map.get("DepYear".toLowerCase());
        entity.depHour = (Integer) map.get("DepHour".toLowerCase());
        entity.depMinute = (Integer) map.get("DepMinute".toLowerCase());

        return entity;
   }

    /**
     * Load Departing destination by IDDeparting.
     */
    private void bindingDeparting(int idDeparting) {
        if (idDeparting > 0) {
            setDeparting(Destination.createEntityFrom(DbManager.getFirstDynamic(Destination.TABLE_NAME, "Destination.ID = " + idDeparting)));
        }
   }

    /**
     * Load Arriving destination by IDArriving.
     */
    private void bindingArriving(int idArriving) {
        if (idArriving > 0) {
            setArriving(Destination.createEntityFrom(DbManager.getFirstDynamic(Destination.TABLE_NAME, "Destination.ID = " + idArriving)));
        }
   }

    private void bindingAircraft(int idAircraft) {
        if (idAircraft > 0) {
            setAircraft(Aircraft.createEntityFrom(DbManager.getFirstDynamic(Aircraft.TABLE_NAME, "Aircraft.ID = " + idAircraft)));
        }
   }

    public String[] getValues() {
        return new String[] {getIdDeparting() + "", getIdArriving() + "",
                getTotalSeats() + "", "'" + getFlightName() + "'",
                isActive() == true ? "1" : "0", getDiscount() + "", getPrice() + "",
                getDuration() + "", getPrice2() + "", getDistance() + "", getIdAircraft() + "",
                depDay + "", depMonth + "", depYear + "", depHour + "", depMinute + ""};
   }

    /***** Following methods is important, please don't modify them *************/

    /**
     * Updating if obj is an existed object otherwise insert
     * @param obj
     * @return true if success otherwise false
     */
  public static boolean save(Flight obj) {
      assert (obj != null);
      if (obj.getId() > 0)
          return update(obj);
      else
          return insert(obj);
  }

    /**
     * Insert given Flight to database.
     * @param obj
     * @return
     */
    private static boolean insert(Flight obj) {
        assert (obj instanceof Flight);
        return DbManager.insert(Flight.tableName, Flight.columns, ((Flight) obj).getValues());
   }

    private static boolean update(Flight obj) {
        assert (obj instanceof Flight);
        return DbManager.update(Flight.tableName, Flight.columns,
                ((Flight) obj).getValues(), "id = " + ((Flight) obj).getId());
   }

    public static boolean delete(Flight obj) {
        assert (obj instanceof Flight);
        return DbManager.delete(Flight.tableName,
                Flight.tableName + ".id = " + ((Flight) obj).getId());
   }

    /**
     * Get the corresponding Flight to where clause.
     * @param where condition (ex: Flight.Price = 1000)
     * @return corresponding Flight or null
     */
    public static Flight getFirstDynamic(String where) {
        Map<String, Object> map = DbManager.getFirstDynamic(Flight.tableName, where);
        return (map != null ? (Flight) Flight.createEntityFrom(map) : null);
   }

    /**
     * Get a list of Flight corresponding to where clause.
     * @param where condition (ex: Flight.Price = 1000)
     * @return corresponding list of Flight or an empty list
     */
    public static List<Flight> getListDynamic(String where) {
        List<Flight> lsResult = new ArrayList<Flight>();

        List<Map<String, Object>> rs = DbManager.getListDynamic(Flight.tableName, where);

        for (Map<String, Object> map : rs) {
            lsResult.add(Flight.createEntityFrom(map));
       }

        return lsResult;
   }

    /****************************************************************************/

    public Date getArrivingDate() {

        Calendar c = Calendar.getInstance();
        c.setTime(getDepartureDate());
        c.add(Calendar.HOUR, duration);

        return c.getTime();
   }

    @XmlElement
     public int getId() {
        return id;
   }

    private void setId(int id) {
        this.id = id;
   }

    @XmlElement
    public int getIdDeparting() {
        return idDeparting;
   }

    public void setIdDeparting(int idDeparting) {
        this.idDeparting = idDeparting;
        bindingDeparting(idDeparting);
   }

    @XmlElement
    public int getIdArriving() {
        return idArriving;
   }

    public void setIdArriving(int idArriving) {
        this.idArriving = idArriving;
        bindingArriving(idArriving);
   }

    public Date getDepartureDate() {
        Calendar c = Calendar.getInstance();
        c.set(depYear, depMonth - 1, depDay, depHour, depMinute);
        return c.getTime();
   }

    public void setDepartureDate(Date departureDate) {
        Calendar c = Calendar.getInstance();
        c.setTime(departureDate);
        depDay = c.get(Calendar.DAY_OF_MONTH);
        depMonth = c.get(Calendar.MONTH) + 1;
        depYear = c.get(Calendar.YEAR);
        depHour = c.get(Calendar.HOUR_OF_DAY);
        depMinute = c.get(Calendar.MINUTE);
   }

    @XmlElement
    public int getTotalSeats() {
        return totalSeats;
   }

    public void setTotalSeats(int totalSeats) {
        this.totalSeats = totalSeats;
   }

    @XmlElement
    public String getFlightName() {
        return flightName;
   }

    public void setFlightName(String flightName) {
        this.flightName = flightName;
   }

    @XmlElement
    public boolean isActive() {
        return isActive;
   }

    public void setActive(boolean isActive) {
        this.isActive = isActive;
   }

    @XmlElement
    public double getDiscount() {
        return discount;
   }

    public void setDiscount(double discount) {
        this.discount = discount;
   }

    public Destination getDeparting() {
        return departing;
   }

    private void setDeparting(Destination departing) {
        this.departing = departing;
   }

    public Destination getArriving() {
        return arriving;
   }

    private void setArriving(Destination arriving) {
        this.arriving = arriving;
   }

    @XmlElement
    public double getPrice() {
        return price;
   }

    public void setPrice(double price) {
        this.price = price;
   }

    @XmlElement
    public int getDuration() {
        return duration;
   }

    public void setDuration(int duration) {
        this.duration = duration;
   }

    @XmlElement
    public double getPrice2() {
        return price2;
   }

    public void setPrice2(double price2) {
        this.price2 = price2;
   }

    @XmlElement
    public double getDistance() {
        return distance;
   }

    public void setDistance(double distance) {
        this.distance = distance;
   }

    @XmlElement
    public int getIdAircraft() {
        return idAircraft;
   }

    private void setIdAircraft(int idAircraft) {
        this.idAircraft = idAircraft;
        bindingAircraft(idAircraft);
   }

    public Aircraft getAircraft() {
        return aircraft;
   }

    public void setAircraft(Aircraft aircraft) {
        this.aircraft = aircraft;
   }

    @XmlElement
    public int getDepDay() {
        return depDay;
   }

    @XmlElement
    public int getDepMonth() {
        return depMonth;
   }

    @XmlElement
    public int getDepYear() {
        return depYear;
   }

    @XmlElement
    public int getDepHour() {
        return depHour;
   }

    @XmlElement
    public int getDepMinute() {
        return depMinute;
   }
}
